#ifndef RACE_TASKS_
#define RACE_TASKS_
#include "stm32f4xx.h"
#include "cmsis_os2.h"
#include "utils.h"

/* 宏和enum------------------------------------------------------*/

/* 比赛任务状态转移事件组标志位 */
#define RE_ARRIVED_ARROW_FRAME_POINT1 (1UL << 0) // RE->RaceEvent
#define RE_ARRIVED_ARROW_FRAME_POINT2 (1UL << 1)
#define RE_FETCH_ARROW_OK (1UL << 2) // 取箭机构上升到一半，底盘开始运动
#define RE_ARRIVED_SHOOT_POINT1 (1UL << 3)
#define RE_ARRIVED_SHHOT_POINT2 (1UL << 4)

typedef enum RaceStatus_e
{
    RS_NONE = 0,
    RS_AT_HOME,                                // 位于启动区内
    RS_GO_TO_ARROW_FRAME_FROM_START,           // 从启动区前往箭架
    RS_FETCHING_ARROW,                         // 执行取箭动作
    RS_GOING_TO_SHOOT_POINT1,                  // 前往射箭点1
    RS_GOING_TO_SHOOT_POINT2,                  // 前往射箭点2
    RS_GOING_TO_ARROW_FRAME_FROM_SHOOT_POINT1, // 从射箭点1前往箭架
    RS_GOING_TO_ARROW_FRAME_FROM_SHOOT_POINT2,    // 从射箭点2前往箭架
    RS_GOING_TO_ARROW_FRAME_POINT1_AFTER_FETCH,   // 取箭后往前走一小段
} RaceStatus_e;                                // TR比赛状态机状态

typedef enum RaceKeyPoints_e
{
    RKP_NONE = 0,
    RKP_ARROW_FRAME1,
    RKP_ARROW_FRAME2,
    RKP_SHOOT_POINT1,
    RKP_SHOOT_POINT2,
} RaceKeyPoints_e; // 比赛地图期望点

typedef struct RaceStateMachine_s
{
    uint8_t state;
    osEventFlagsId_t *event;
    RaceKeyPoints_e target_point_index;     //设计这一变量的目的是将取箭点、射箭点之间的跑动抽象成图和边，顶层只设定期望点，具体跑什么路径由状态机决策
    uint8_t shoot_point_arrived_count;      // 射箭点访问次数统计
    uint8_t arrived_arrow_frame_point1 : 1; // 到达箭架点1：开始进入纯跑点模式
    uint8_t arrived_arrow_frame_point2 : 1; // 到达箭架点2：可以执行取箭动作
    uint8_t fetch_arrow_ok : 1;             // 取箭成功，手爪上升至一半，底盘开始运动
    uint8_t arrived_shoot_point1 : 1;       // 到达射箭点1
    uint8_t arrived_shoot_point2 : 1;       // 到达射箭点2
    uint8_t arrow_blank : 1;                // 箭空
    uint8_t hitted_wall : 1;                // 撞墙标志, 到达箭架点2时复位
    uint8_t arrow_shooted : 1;              // 箭已射出，配合arrow_blank
} RaceStateMachine_s;

/* 全局变量-------------------------------------------------------*/
extern RaceStateMachine_s RaceStateMachine;
extern const Point2D ArrowFramePoint1;
extern const Point2D ArrowFramePoint2;
extern const Point2D ShootPoint1;
extern const Point2D ShootPoint2;

/* 函数声明-------------------------------------------------------*/
void RaceTask_JudgeHittedWall(void);

#endif